//! @Author: DengLibin
//! @Date: Create in 2024-07-24 09:53:21
//! @Description: redis组件

use std::sync::Arc;

use redis::{aio::MultiplexedConnection, AsyncCommands, Client};
use serde::{Deserialize, Serialize};
use tokio::sync::Mutex;

use crate::sys::global::{to_global_result, GlobalResult};

/// @Author: DengLibin
/// @Date: Create in 2024-07-24 09:55:26
/// @Description: 创建客户端
/// @param url: redis url example: "redis://127.0.0.1/"
pub async fn create_redis_client(url: &str) -> GlobalResult<Client> {
    // 创建 Redis 客户端
    to_global_result(redis::Client::open(url))
}

/// @Author: DengLibin
/// @Date: Create in 2024-07-24 10:06:25
/// @Description: 获取一个多路复用连接
pub async fn get_multiplexed_async_connection(
    client: &Client,
) -> GlobalResult<MultiplexedConnection> {
    to_global_result(client.get_multiplexed_async_connection().await)
}

/// @Author: DengLibin
/// @Date: Create in 2024-07-24 10:40:31
/// @Description: 设置值
pub async fn set_string_value(
    key: &str,
    value: &str,
    conn: Arc<Mutex<MultiplexedConnection>>,
) -> GlobalResult<()> {
    // 设置一个键值
    let mut conn = conn.lock().await;

    let r: Result<(), redis::RedisError> = conn.set(key, value).await;

    to_global_result(r)
}

/// @Author: DengLibin
/// @Date: Create in 2024-07-24 10:40:31
/// @Description: 设置值 指定过期时间
pub async fn set_string_value_ex(
    key: &str,
    value: &str,
    expire_sec: u64,
    conn: Arc<Mutex<MultiplexedConnection>>,
) -> GlobalResult<()> {
    // 设置一个键值
    let mut conn = conn.lock().await;

    let r: Result<(), redis::RedisError> = conn.set_ex(key, value, expire_sec).await;

    to_global_result(r)
}
/// @Author: DengLibin
/// @Date: Create in 2024-07-24 11:09:39
/// @Description: 获取值
pub async fn get_string_value(
    key: &str,
    conn: Arc<Mutex<MultiplexedConnection>>,
) -> GlobalResult<String> {
    // 设置一个键值
    let mut conn = conn.lock().await;

    let r: Result<String, redis::RedisError> = conn.get(key).await;

    to_global_result(r)
}
/// @Author: DengLibin
/// @Date: Create in 2024-07-24 11:24:42
/// @Description: 设置一个结构体对象
pub async fn set_obj_value<T>(
    key: &str,
    t: T,
    conn: Arc<Mutex<MultiplexedConnection>>,
) -> GlobalResult<()>
where
    T: Serialize + for<'r> Deserialize<'r>,
{
    // 序列化结构体为 JSON 字符串
    let json_str = to_global_result(serde_json::to_string(&t))?;
    set_string_value(key, &json_str, conn).await
}
/// @Author: DengLibin
/// @Date: Create in 2024-07-24 11:24:58
/// @Description: 带过期时间
pub async fn set_obj_value_ex<T>(
    key: &str,
    t: T,
    expire_sec: u64,
    conn: Arc<Mutex<MultiplexedConnection>>,
) -> GlobalResult<()>
where
    T: Serialize + for<'r> Deserialize<'r>,
{
    // 序列化结构体为 JSON 字符串
    let json_str = to_global_result(serde_json::to_string(&t))?;
    set_string_value_ex(key, &json_str, expire_sec, conn).await
}

/// @Author: DengLibin
/// @Date: Create in 2024-07-24 11:28:07
/// @Description: 获取结构体对象
pub async fn get_obj_value<T>(key: &str, conn: Arc<Mutex<MultiplexedConnection>>) -> GlobalResult<T>
where
    T: Serialize + for<'r> Deserialize<'r>,
{
    let json_str = get_string_value(key, conn).await?;
    to_global_result(serde_json::from_str::<T>(&json_str))
}

 /// @Author: DengLibin
 /// @Date: Create in 2024-07-24 11:43:08
 /// @Description: 删除
pub async fn del_val(key: &str, conn: Arc<Mutex<MultiplexedConnection>>) -> GlobalResult<()> {
   
    let mut conn = conn.lock().await;
    let r: Result<(), redis::RedisError> = conn.del(key).await;
    to_global_result(r)
}
